/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package be.ugent.medirem.persistence.facade;

import be.ugent.medirem.persistence.entity.Measurement;
import be.ugent.medirem.persistence.entity.MeasurementType;
import be.ugent.medirem.persistence.entity.Patient;
import be.ugent.medirem.persistence.entity.details.MeasurementDetails;
import be.ugent.medirem.persistence.entity.values.MeasurementValues;
import be.ugent.medirem.persistence.exception.EntityNotFoundException;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Thomas Roelens
 */
@Stateless
public class MeasurementDaoBean implements MeasurementDaoLocal {

    @PersistenceContext
    private EntityManager em;

    public Long create(MeasurementValues details) throws IllegalArgumentException {
        Measurement measurement = null;
        MeasurementType type = null;

        try {
            type = em.find(MeasurementType.class, details.getTypeId());

        } catch (Exception ex) {
            throw new EJBException(ex);
        }

        try {
            measurement = new Measurement(type, details.getValue(), details.getDateTaken());
            persist(measurement);
        } catch (Exception ex) {
            throw new EJBException(ex);
        }

        return measurement.getId();
    }

    public void remove(Long measurementId) throws IllegalArgumentException, EntityNotFoundException {
        Measurement measurement = null;
        if (measurementId == null) {
            throw new IllegalArgumentException("measurement id is null");
        }
        try {
            measurement = em.find(Measurement.class, measurementId);

            if (measurement == null) {
                throw new EntityNotFoundException();
            } else {
                measurement = em.merge(measurement);
                em.remove(measurement);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public void update(Long measurementId, MeasurementValues details) throws IllegalArgumentException, EntityNotFoundException {
        Measurement measurement = null;
        if (measurementId == null) {
            throw new IllegalArgumentException("measurement id is null");
        }
        try {
            measurement = em.find(Measurement.class, measurementId);

            if (measurement == null) {
                throw new EntityNotFoundException();
            } else {
                if (details.getTypeId() != null) {
                    MeasurementType newType = em.find(MeasurementType.class, details.getTypeId());
                    measurement.setType(newType);
                }
                if (details.getValue() != 0) {
                    measurement.setMeasurementValue(details.getValue());
                }
                if (details.getDateTaken() != null) {
                    measurement.setDateTaken(details.getDateTaken());
                }
                em.merge(measurement);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public MeasurementDetails getDetails(Long measurementId) throws IllegalArgumentException, EntityNotFoundException {
        Measurement measurement = null;
        MeasurementDetails details = null;

        if (measurementId == null) {
            throw new IllegalArgumentException("measurement id is null");
        }
        try {
            measurement = em.find(Measurement.class, measurementId);

            if (measurement == null) {
                throw new EntityNotFoundException();
            } else {
                details = new MeasurementDetails(measurement.getId(), measurement.getType().getName(), measurement.getType().getUnit().getName(), measurement.getMeasurementValue(), measurement.getDateTaken());
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }

        return details;
    }

    public void addMeasurement(Long patientId, Long measurementId) {
        Patient patient = null;

        if (patientId == null) {
            throw new IllegalArgumentException("Patient id is null");
        }
        try {
            patient = em.find(Patient.class, patientId);

            if (patient == null) {
                throw new EntityNotFoundException();
            } else {
                Measurement newMeasurement = em.find(Measurement.class, measurementId);
                patient.addMeasurement(newMeasurement);
                em.merge(patient);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public void removeMeasurement(Long patientId, Long measurementId) {
        Patient patient = null;

        if (patientId == null) {
            throw new IllegalArgumentException("Patient id is null");
        }
        try {
            patient = em.find(Patient.class, patientId);

            if (patient == null) {
                throw new EntityNotFoundException();
            } else {
                Measurement measurement = em.find(Measurement.class, measurementId);
                patient.removeMeasurement(measurement);
                em.merge(patient);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public List<MeasurementDetails> getMeasurements(Long patientId, String measurementType) {
        Patient patient = null;
        List<MeasurementDetails> measurementList = new ArrayList<MeasurementDetails>();

        if (patientId == null) {
            throw new IllegalArgumentException("Patient id is null");
        }
        try {
            patient = em.find(Patient.class, patientId);

            if (patient == null) {
                throw new EntityNotFoundException();
            } else {
                for (Measurement m : patient.getMeasurements()) {
                    if (m.getType().getName().equals(measurementType)) {
                        MeasurementDetails details = new MeasurementDetails(m.getId(), m.getType().getName(), m.getType().getUnit().getName(), m.getMeasurementValue(), m.getDateTaken());
                        details.setTypeId(m.getType().getId());
                        measurementList.add(details);
                    }
                }
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }

        return measurementList;
    }

    public void persist(Object object) {
        em.persist(object);
    }
}
